package com.currency.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.currency.exception.AppException;
import com.currency.mapper.*;
import com.currency.pojo.*;
import com.currency.request.BindOilCardRequest;
import com.currency.request.ThirdBindRequest;
import com.currency.response.BaseResponse;
import com.currency.response.QueryAccountResponse;
import com.currency.service.AccountService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Autowired
    private PayAccountMapper payAccountMapper;
    @Autowired
    private BankcardInfoMapper bankcardInfoMapper;
    @Autowired
    private WytMonthlyClientArrearsMapper wytMonthlyClientArrearsMapper;
    @Autowired
    private WytArrearsDetailMapper detailMapper;

    @Autowired
    WytCoinsTradeResumeMapper coinsTradeResumeMapper;

    @Value("${sys.machineId}")
    private Integer machineId;


    private WytMonthlyClientArrearsPojo getLastMonthArrears(String userId) {
        Date date = new Date();
        String arrearsYearMonth;
        String year = DateUtils.formatDate(date, "yyyy");
        int month = Integer.parseInt(DateUtils.formatDate(date, "MM"));
        if (month > 1) {
            month = month - 1;
            arrearsYearMonth = year + "-" + month;
        } else {
            arrearsYearMonth = (Integer.parseInt(year) - 1) + "-12";
        }
        return wytMonthlyClientArrearsMapper.selectOne(new QueryWrapper<WytMonthlyClientArrearsPojo>().eq("user_id", userId).eq("arrears_year_month", arrearsYearMonth));

    }

    @GetMapping("/query-arrears")
    @ApiOperation(value = "查询用户上月欠款是否已经结清")
    public BaseResponse queryArrears(String userId) {
        WytMonthlyClientArrearsPojo arrearsPojo = getLastMonthArrears(userId);
        if (arrearsPojo == null || StringUtils.equalsIgnoreCase(arrearsPojo.getArrearsStatus(), "S")) {
            return new BaseResponse("cey0000", "欠款已经还钱，可以发货");
        } else {
            return new BaseResponse("cey0001", "欠款未还钱，不能发货");
        }
    }

    private void insertResume(BigDecimal amount, int type, String userId, String outId, String msg) {
        WytCoinsTradeResumePojo pojo = new WytCoinsTradeResumePojo();
        pojo.setAmount(amount);
        pojo.setType(type);
        pojo.setUserId(userId);
        pojo.setOutId(outId);
        pojo.setMsg(msg);
        coinsTradeResumeMapper.insert(pojo);
    }

    @GetMapping("/repay-arrears")
    @ApiOperation(value = "还清欠款")
    public BaseResponse repayArrears(String userId) throws AppException {
        WytMonthlyClientArrearsPojo arrearsPojo = getLastMonthArrears(userId);
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(userId);
        if (arrearsPojo == null || StringUtils.equalsIgnoreCase(arrearsPojo.getArrearsStatus(), "S")) {
            return new BaseResponse("cey0000", "您上月欠款已经缴清");
        }
        if (accountPojo.getUserCoins() < arrearsPojo.getAmount()) {
            throw new AppException("cey0002", "您的金币余额不足以归还欠款");
        }
        // 归还欠款
        accountPojo.setUserCoins(accountPojo.getUserCoins() - arrearsPojo.getAmount());
        payAccountMapper.updateById(accountPojo);

        arrearsPojo.setArrearsStatus("S");
        wytMonthlyClientArrearsMapper.updateById(arrearsPojo);
        // 插入归还明细
        WytArrearsDetailPojo detailPojo = new WytArrearsDetailPojo();
        detailPojo.setOrderId("");
        detailPojo.setMessage("归还欠款");
        detailPojo.setUserId(userId);
        detailPojo.setId("arrA" + IdUtil.createSnowflake(2, 2).nextIdStr());
        detailPojo.setArrearsYearMonth(arrearsPojo.getArrearsYearMonth());
        detailPojo.setArrearsType(WytArrearsDetailPojo.ARREARS_TYPE_A);
        detailPojo.setAmount(arrearsPojo.getAmount());
        detailMapper.insert(detailPojo);

        //插入交易明细
        insertResume(new BigDecimal(arrearsPojo.getAmount()).divide(new BigDecimal("100")), WytCoinsTradeResumePojo.MUL, userId, detailPojo.getId(), "归还欠款");

        return new BaseResponse("cey0000", "欠款归还完成");
    }


    @GetMapping("/query")
    @ApiOperation(value = "查询、新建账户信息")
    public QueryAccountResponse query(String userId) throws AppException {
        if (StringUtils.isBlank(userId)) {
            throw new AppException("cey1000", "参数不合法");
        }
        QueryAccountResponse response = new QueryAccountResponse();
        // 查询用户信息是否存在
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(userId);
        if (accountPojo == null || StringUtils.isBlank(accountPojo.getUserId())) {
            // 新建账户信息
            accountPojo = new WytCurrencyPayAccountPojo();
            accountPojo.setUserId(userId);
            accountPojo.setUserCoins(0);
            accountPojo.setUserFreezeCoins(0);
            int i = payAccountMapper.insert(accountPojo);
            if (i <= 0) {
                throw new AppException("cey9999", "系统维护中，请稍后再试");
            }
            response.setUserCoins(0);
            response.setUserFreezeCoins(0);
            response.setUserId(userId);
            response.setOilCard("");
            response.setOilCoins(0);
            response.setArrearsCoins(0);
        } else {
            // 查询账户信息
            response.setUserId(accountPojo.getUserId());
            response.setUserFreezeCoins(accountPojo.getUserFreezeCoins());
            response.setUserCoins(accountPojo.getUserCoins());
            response.setOilCard(accountPojo.getOilCard());
            response.setOilCoins(accountPojo.getOilCoins());
            QueryWrapper<WytCurrencyBankcardInfoPojo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", accountPojo.getUserId()).eq("bind_status", 0);
            List<WytCurrencyBankcardInfoPojo> bnkList = bankcardInfoMapper.selectList(queryWrapper);
            if (bnkList != null && bnkList.size() > 0) {
                response.setCardList(bnkList);
            }
            WytMonthlyClientArrearsPojo arrearsPojo = getLastMonthArrears(userId);
            if (arrearsPojo == null || StringUtils.equalsIgnoreCase(arrearsPojo.getArrearsStatus(), "S")) {
                // 欠款已经还清
                response.setArrearsCoins(0);
            } else {
                response.setArrearsCoins(arrearsPojo.getAmount());
            }


        }
        response.setErrCode("cey0000");
        response.setErrMsg("查询成功");
        return response;
    }

    @PostMapping(value = "/third-bind")
    @ApiOperation(value = "第三方绑定接口")
    public BaseResponse thirdBind(@RequestBody ThirdBindRequest request) throws AppException {
        WytCurrencyPayAccountPojo pojo = payAccountMapper.selectById(request.getUserId());
        if (pojo == null || StringUtils.isBlank(pojo.getUserId())) {
            throw new AppException("cey9999", "用户不存在");
        }
        // 绑定微信
        if (StringUtils.isNotBlank(request.getWxOpenid())) {
            List<WytCurrencyPayAccountPojo> list = payAccountMapper.selectList(new QueryWrapper<WytCurrencyPayAccountPojo>().eq("user_wx_id", request.getWxOpenid()));
            if (list != null && list.size() > 1) {
                throw new AppException("cey9999", "当前微信已经被其他手机号绑定");
            } else {
                pojo.setUserWxId(request.getWxOpenid());
            }
        }
        // 绑定支付宝
        if (StringUtils.isNotBlank(request.getAlipayId())) {
            List<WytCurrencyPayAccountPojo> list = payAccountMapper.selectList(new QueryWrapper<WytCurrencyPayAccountPojo>().eq("user_ap_id", request.getWxOpenid()));
            if (list != null && list.size() > 1) {
                throw new AppException("cey9999", "当前支付宝账号已经被其他手机号绑定");
            } else {
                pojo.setUserApId(request.getAlipayId());
            }
        }
        // 绑定银联
        if (StringUtils.isNotBlank(request.getBankUnionId())) {
            List<WytCurrencyPayAccountPojo> list = payAccountMapper.selectList(new QueryWrapper<WytCurrencyPayAccountPojo>().eq("user_yl_id", request.getWxOpenid()));
            if (list != null && list.size() > 1) {
                throw new AppException("cey9999", "当前银联已经被其他手机号绑定");
            } else {
                pojo.setUserYlId(request.getBankUnionId());
            }
        }

        payAccountMapper.updateById(pojo);

        return new BaseResponse("cey0000", "第三方关系绑定成功");
    }

    @PostMapping(value = "/bindOilCard")
    @ApiOperation(value = "油卡绑定，更新")
    public BaseResponse bindOilCard(@RequestBody BindOilCardRequest request) throws AppException {
        // 查询客户油卡信息
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(request.getUserId());
        if (accountPojo == null || StringUtils.isBlank(accountPojo.getUserId())) {
            throw new AppException("cey9999", "用户数据为空");
        }

        // 更换油卡信息
        accountPojo.setOilCard(request.getOilCard());
        payAccountMapper.updateById(accountPojo);
        return new BaseResponse("cey0000", "更新油卡成功");
    }

    @PostMapping(value = "unbindOilCard")
    @ApiOperation(value = "解绑油卡")
    public BaseResponse unbindOilCard(@RequestBody BindOilCardRequest request) throws AppException {
        // 查询客户油卡信息
        WytCurrencyPayAccountPojo accountPojo = payAccountMapper.selectById(request.getUserId());
        if (accountPojo == null || StringUtils.isBlank(accountPojo.getOilCard())) {
            throw new AppException("cey9999", "用户油卡信息为空");
        }
        accountPojo.setOilCard("");
        payAccountMapper.updateById(accountPojo);
        return new BaseResponse("cey0000", "解绑油卡成功！");
    }

    @RequestMapping(value = "/bind", method = RequestMethod.POST)
    @ApiOperation(value = "卡片绑定或者解绑，通过 bindStatus的值来判定")
    public BaseResponse bindCard(@RequestBody WytCurrencyBankcardInfoPojo request) throws AppException {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("user_id", request.getUserId());
        paramMap.put("card_number", request.getCardNumber());
        List<WytCurrencyBankcardInfoPojo> bankcardInfoPojoList = bankcardInfoMapper.selectByMap(paramMap);
        if (bankcardInfoPojoList != null && bankcardInfoPojoList.size() > 0) {
            //已有卡片，绑定或者解绑
            WytCurrencyBankcardInfoPojo pojo = bankcardInfoPojoList.get(0);
            pojo.setBindStatus(request.getBindStatus());
            bankcardInfoMapper.updateById(pojo);
        } else {
            if (StringUtils.isBlank(request.getUserId()) || StringUtils.isBlank(request.getUserName()) || StringUtils.isBlank(request.getCardNumber()) || StringUtils.isBlank(request.getCardBankName()) || StringUtils.isBlank(request.getCardBindMobile())) {
                throw new AppException("cey0010", "用户ID，绑卡客户姓名，银行卡号，银行名称，银行预留手机号不能为空");
            }
            request.setInfoId(IdUtil.getSnowflake(machineId, 0).nextIdStr());
            request.setBindStatus(0);
            // 新卡设置为默认卡
            if (request.getDefaultFlag() == 1) {
                defaultCardUpdate(bankcardInfoPojoList, request.getCardNumber());
            }
            bankcardInfoMapper.insert(request);
        }
        return new BaseResponse("cey0000", "绑定/解绑成功");
    }

    @RequestMapping(value = "/update-card", method = RequestMethod.POST)
    @ApiOperation(value = "卡片信息更新，默认卡切换")
    public BaseResponse updateCard(@RequestBody WytCurrencyBankcardInfoPojo request) throws AppException {
        if (StringUtils.isBlank(request.getInfoId()) || StringUtils.isBlank(request.getUserId()) || StringUtils.isBlank(request.getUserName()) || StringUtils.isBlank(request.getCardNumber()) || StringUtils.isBlank(request.getCardBankName()) || StringUtils.isBlank(request.getCardBindMobile())) {
            throw new AppException("cey0011", "绑定的信息ID不能为空");
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("user_id", request.getUserId());
        List<WytCurrencyBankcardInfoPojo> bankcardInfoPojoList = bankcardInfoMapper.selectByMap(paramMap);
        for (WytCurrencyBankcardInfoPojo data : bankcardInfoPojoList) {
            if (StringUtils.equalsIgnoreCase(data.getCardNumber(), request.getCardNumber())) {
                if (!StringUtils.equalsIgnoreCase(data.getInfoId(), request.getInfoId())) {
                    throw new AppException("cey0012", "存在同银行卡号的信息，建议直接修改同卡号记录");
                }
            }
        }
        WytCurrencyBankcardInfoPojo data = bankcardInfoMapper.selectById(request.getInfoId());
        if (!StringUtils.equalsIgnoreCase(data.getDefaultFlag() + "", request.getDefaultFlag() + "") && request.getDefaultFlag() == 1) {
            //需要切换默认卡
            defaultCardUpdate(bankcardInfoPojoList, request.getCardNumber());
        }
        bankcardInfoMapper.updateById(request);
        return new BaseResponse("cey0000", "卡片信息更新成功");
    }

    private void defaultCardUpdate(List<WytCurrencyBankcardInfoPojo> list, String defaultCardNumber) {
        if (list == null || list.size() == 0) {
            return;
        }
        for (WytCurrencyBankcardInfoPojo data : list) {
            if (!StringUtils.equalsIgnoreCase(data.getCardNumber(), defaultCardNumber)) {
                data.setDefaultFlag(0);
                bankcardInfoMapper.updateById(data);
            }
        }
    }

}